package com.hp.bon.sgw.threads;

import static com.hp.bon.sgw.Constants.LOG;

public abstract class TaskThread extends Thread {
	private volatile boolean exit = false;
	private boolean isSleeping = false;
	protected long sleepTime;// 发送一轮消息的间隔时间

	protected long runTime;// 本次轮询时刻
	protected long lastrunTime;// 上一次轮询时刻
	/**
	 * 退出命令，接收到此命令后，唤醒线程，做收尾工作
	 */
	public void exit() {
		System.out.println(this.getName()+" exit...");
		exit = true;
		kickOff();
	}

	public void setSleepTime(long sleepTime) {
		this.sleepTime = sleepTime;
	}

	private void kickOff() {
		if (isSleeping) {
			interrupt();
		}
	}

	public TaskThread() {
		runTime = System.currentTimeMillis();
		sleepTime = 10 * 1000;// 默认为10秒执行一次
		this.setDaemon(true);
	}

	@Override
	public void run() {
		LOG.info(this.getName() + " running");
		processAfterStart();
		long needSleep = sleepTime;
		while (!exit) {
			needSleep = sleepTime;
			// 执行主循环体
			try {
				// 记录开始运行的时间
				lastrunTime = runTime;
				runTime = System.currentTimeMillis();
				// 开始运行
				process();

				// 计算运行消耗时间
				long duration = System.currentTimeMillis() - runTime;
				// 计算需要剩余的sleep时间，如果剩余时间 大于(sleepTime / 4)
				// ,则进行sleep，否则不允许sleep，直接下一个循环操作
				needSleep = sleepTime - duration;
			} catch (Exception ex) {
				LOG.warn(this.getName() + " throw exception " + ex.getMessage(), ex);
			} catch (Error o) {
				LOG.warn(this.getName() + " throw Error " + o.getMessage(), o);
			}

			// 执行完Sleep
			if (needSleep > (sleepTime >> 2)) {
				try {
					isSleeping = true;
					Thread.sleep(needSleep);
					isSleeping = false;
				} catch (InterruptedException ex) {
					isSleeping = false;
					LOG.info(this.getName() + " interrupted");
				}
			}
		}
		processBeforeExit();
		LOG.info(this.getName() + " exiting");
	}

	/**
	 * �߳�������Ķ�����һ����Sleepһ��ʱ�䣬��ִ��process����
	 */
	protected void processAfterStart() {
		try {
			isSleeping = true;
			Thread.sleep(sleepTime);
			isSleeping = false;
		} catch (InterruptedException ex) {
			isSleeping = false;
			LOG.info(this.getName() + " interrupted");
		}
	}

	/**
	 * �߳��˳�ǰ�Ķ�����һ�����˳�Whileѭ����������?��
	 */
	protected void processBeforeExit() {
	}

	protected abstract void process();
}
